#!/usr/bin/env python

import sys
sys.path.append('/usr/share/inkscape/extensions')
import inkex, simplestyle
from simplestyle import *
import re

class SudokuGrid(inkex.Effect):

    """
    Creates a sudoku grid.
    """

    def __init__(self):
        """
        Constructor. Initializes variables.
        """

        inkex.Effect.__init__(self)
        
        self.OptionParser.add_option('--variant', action='store', type='string', dest='variant', default='classic', help="Choose the desired sudoku variant.")
        self.OptionParser.add_option('--helpnumbers', action='store', type='string', dest='helpnumbers', default='', help="Here you can specify help numbers to be inserted into the crossword. Format: row,column,number;")

    def effect(self):
        """
        Creates a sudoku grid.
        """
        
        # get svg data
        svg = self.document.getroot()
                
        # create a layer
        layer = inkex.etree.SubElement(svg, 'g')
        layer.set(inkex.addNS('label', 'inkscape'), 'Sudoku')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        w = 9
        h = 9
        cell_width = 25
        cell_height = 25

        if self.options.variant == "mini":
            w = 6
            h = 6
            # draw rectangles
            for i in range(6):
                for j in range(6):
                    
                    style = {'stroke':'#000000', 'fill':'none'}                            
                    square_attribs = {
                        'style': simplestyle.formatStyle(style),
                        'height': '25',
                        'width': '25',
                        'x': str(i*25),
                        'y': str(j*25)
                        } 
                    shape = inkex.etree.Element(inkex.addNS('rect','svg'), square_attribs)
                    layer.append(shape)

            # create large edges
            for i in range(2):
                for j in range(3):
                    style = {'stroke':'#000000', 'stroke-width': '3', 'fill':'none'}
                    square_attribs = {
                        'style': simplestyle.formatStyle(style),
                        'height': str(25*2),
                        'width': str(25*3),
                        'x': str(25*3*i),
                        'y': str(25*2*j)
                        }
                    shape = inkex.etree.Element(inkex.addNS('rect','svg'), square_attribs)
                    layer.append(shape)


        if self.options.variant == "sudokux" or self.options.variant == "classic" or self.options.variant == "hyper":
            # draw rectangles
            for i in range(9):
                for j in range(9):
                    
                    style = {'stroke':'#000000', 'fill':'none'}
                    if self.options.variant == "sudokux":
                        if (i == j) or (j == 9-(i+1)):
                            style = {'stroke':'#000000', 'fill':'#bbbbbb'}
                    elif self.options.variant == "hyper":
                        if not((i == 0) or (i == 4) or (i == 8) or (j == 0) or (j == 4) or (j == 8)):
                            style = {'stroke':'#000000', 'fill':'#bbbbbb'}
                            
                    square_attribs = {
                        'style': simplestyle.formatStyle(style),
                        'height': '25',
                        'width': '25',
                        'x': str(i*25),
                        'y': str(j*25)
                        } 
                    shape = inkex.etree.Element(inkex.addNS('rect','svg'), square_attribs)
                    layer.append(shape)
                            
            # create large edges
            for i in range(3):
                for j in range(3):
                    style = {'stroke':'#000000', 'stroke-width': '3', 'fill':'none'}
                    square_attribs = {
                        'style': simplestyle.formatStyle(style),
                        'height': str(25*3),
                        'width': str(25*3),
                        'x': str(25*3*i),
                        'y': str(25*3*j)
                        }
                    shape = inkex.etree.Element(inkex.addNS('rect','svg'), square_attribs)
                    layer.append(shape)

        elif self.options.variant == "samurai":

            w = 21
            h = 21

            # create large edges
            for i in range(7):
                for j in range(7):

                    if not(
                        ((i == 3) and ((j == 0) or (j == 1))) or
                        ((j == 3) and ((i == 0) or (i == 1))) or
                        ((i == 3) and ((j == 5) or (j == 6))) or
                        ((j == 3) and ((i == 5) or (i == 6)))):
                        style = {'stroke':'#000000', 'stroke-width': '3', 'fill':'none'}
                        square_attribs = {
                            'style': simplestyle.formatStyle(style),
                            'height': str(25*3),
                            'width': str(25*3),
                            'x': str(25*3*i),
                            'y': str(25*3*j)
                            }
                        shape = inkex.etree.Element(inkex.addNS('rect','svg'), square_attribs)
                        layer.append(shape)

                        # create little squares            
                        for k in range(3):
                            for z in range(3):
                                style = {'stroke':'#000000', 'fill':'none'}                            
                                square_attribs = {
                                    'style': simplestyle.formatStyle(style),
                                    'height': '25',
                                    'width': '25',
                                    'x': str((i*3*25) + (k*25)),
                                    'y': str((j*3*25) + (z*25))
                                    } 
                                shape = inkex.etree.Element(inkex.addNS('rect','svg'), square_attribs)
                                layer.append(shape)
        

        # draw help numbers
        if len(self.options.helpnumbers) > 0:
            numbers = self.options.helpnumbers.split(";")
            numbers_style = {'text-align': 'center', 'fill': '#000000', 'stroke': 'none', 'font-size':20}
            for n in numbers:
                # check format
                p = re.compile("[0-9]+[,][0-9]+[,][0-9]{1}")                
                if p.match(n):
                    n1 = n.split(",")
                    # TODO: if the type is samurai, check numbers position
                    if (int(n1[0])-1 < int(h)) and (int(n1[1])-1 < int(w)):
                        numberlabel_attribs = {
                            'x': str(5 + (int(n1[1])-1) * cell_width),
                            'y': str(-5 + int(n1[0]) * cell_height),
                            'style': formatStyle(numbers_style),
                            }                
                        numberlabel = inkex.etree.Element(inkex.addNS('text','svg'), numberlabel_attribs)                    
                        numberlabel.text = n1[2][0]
                        layer.append(numberlabel)
         

# Let's the magic begin!        

effect = SudokuGrid()
effect.affect()
